import { useState } from 'react'

interface StateProps<D> {
  data: D | null
  error: Error | null
  stat: 'idle' | 'error' | 'loading' | 'success'
}

const defaultInitialState: StateProps<null> = {
  data: null,
  error: null,
  stat: 'idle',
}

/**
 * @description: 处理异步状态的hook
 * @param { Type } D
 * @param  { StateProps<D> } initialState
 * @return {*}
 */
export const useAsync = <D>(initialState?: StateProps<D>) => {
  const [state, setState] = useState<StateProps<D>>({
    ...initialState,
    ...defaultInitialState,
  })
  const setData = (data: D) => {
    setState({
      data,
      error: null,
      stat: 'success',
    })
  }

  const setLoading = () => {
    setState({
      ...state,
      stat: 'loading',
    })
  }
  const setError = (error: Error) => {
    setState({
      error,
      data: null,
      stat: 'error',
    })
  }

  const run = (promise: Promise<D>) => {
    if (!promise || !promise.then) throw new Error('请传入Promise类型')
    setLoading()
    return promise
      .then((data) => {
        setData(data)
        return data
      })
      .catch((error) => {
        setError(error)
        return error
      })
  }

  return {
    isIdle: state.stat === 'idle',
    isError: state.stat === 'error',
    isLoading: state.stat === 'loading',
    isSuccess: state.stat === 'success',
    setData,
    setLoading,
    setError,
    run,
    ...state,
  }
}
